package com.hddf.project.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.hibernate.Session;
import org.kommii.mysql_conn_pool.SessionProvider;

import com.hddf.project.base.BaseService;
import com.hddf.project.dao.PlanDao;
import com.hddf.project.dao.ProjectDao;
import com.hddf.project.impl.PlanDaoImpl;
import com.hddf.project.impl.ProjectDaoImpl;
import com.hddf.project.pojos.FirstCategory;
import com.hddf.project.pojos.Project;
import com.hddf.project.pojos.ProjectPlan;
import com.hddf.project.pojos.ProjectPlanItem;
import com.hddf.project.pojos.SecondCategory;
import com.hddf.project.pojos.ThirdCategory;
import com.hddf.project.util.O;

public class PlanService extends BaseService {

	private static PlanService ps = null;
	private static PlanDao pd = null;
	private static ProjectDao projectDao = null;
	private static CommentService cts = null;

	static {
		if (null == ps) {
			ps = new PlanService();
		}
		if (null == pd) {
			pd = new PlanDaoImpl();
		}
		if (null == projectDao) {
			projectDao = new ProjectDaoImpl();
		}
		if (null == cts) {
			cts = CommentService.getInService();
		}
	}

	public static PlanService getInService() {
		return ps;
	}

	/**
	 * 添加计划
	 * 
	 * @return
	 * @throws Exception
	 */
	public ProjectPlan addPlan(String name) throws Exception {
		ProjectPlan pp = new ProjectPlan();
		pp.setInputTime(O.getTimestamp3());
		pp.setName(name);
		pp.setUdpateTime(O.getTimestamp3());
		super.addObject(pp);
		return pp;
	}

	/**
	 * 修改计划
	 * 
	 * @return
	 * @throws Exception
	 */
	public boolean updatePlan(Integer id, String name) throws Exception {
		ProjectPlan pp = this.getPlanById(id);
		pp.setName(name);
		pp.setUdpateTime(O.getTimestamp3());
		super.updateObject(pp);
		return true;
	}

	/**
	 * 根据ID获取计划
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	public ProjectPlan getPlanById(Integer id) throws Exception {
		return (ProjectPlan) super.getObjectById(id, ProjectPlan.class);
	}

	/**
	 * 根据ID获取计划配置数据
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	public ProjectPlanItem getPlanItemById(Integer id) throws Exception {
		return (ProjectPlanItem) super.getObjectById(id, ProjectPlanItem.class);
	}

	/**
	 * 删除计划
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	public boolean deletePlan(Integer id) throws Exception {
		ProjectPlan pp = this.getPlanById(id);
		if (null != pp) {
			super.deleteObject(pp);

			List<ProjectPlanItem> ppiList = this.getPlanItemByPlanId(id);
			if (O.ckLt(ppiList)) {// 如果计划含有项目,则删除计划的项目的数据
				for (ProjectPlanItem ppi : ppiList) {
					this.deleteProjectPlanItem(ppi.getId());
				}
			}

		}
		return true;
	}

	/**
	 * 根据ID查询计划中的项目
	 * 
	 * @param id
	 * @return
	 * @throws Exception
	 */
	public List<ProjectPlanItem> getPlanItemByPlanId(Integer id) throws Exception {
		Session s = null;
		try {
			List<ProjectPlanItem> ppiList = null;
			s = SessionProvider.getSession();
			ppiList = pd.getPlanItemByPlanId(id, s);
			SessionProvider.commitSession(s);
			return ppiList;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			throw new Exception(e);
		}
	}

	/**
	 * 根据项目ID和计划ID查询数量
	 * 
	 * @param projectId
	 * @param planId
	 * @param s
	 * @return
	 */
	public int countPlanItem(int projectId, int planId) {
		Session s = null;
		try {
			s = SessionProvider.getSession();
			int result = pd.countPlanItem(projectId, planId, s);
			SessionProvider.commitSession(s);
			return result;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			e.printStackTrace();
			return 1;
		}
	}

	/**
	 * 添加计划配置
	 * 
	 * @return
	 * @throws Exception
	 */
	public ProjectPlanItem addPlanItem(Integer projectPlanId, Integer projectId) throws Exception {
		int result = this.countPlanItem(projectId, projectPlanId);
		if (result == 0) {
			ProjectPlanItem ppi = new ProjectPlanItem();
			ppi.setInputTime(O.getTimestamp3());
			ppi.setProjectId(projectId);
			ppi.setProjectPlanId(projectPlanId);
			ppi.setRemarks("");
			ppi.setState(0);
			super.addObject(ppi);

			Project p = (Project) super.getObjectById(projectId, Project.class);
			if (null != p) {
				p.setIspass(2);
				super.updateObject(p);
			}
			return ppi;
		}
		return null;
	}

	// /**
	// * 添加计划配置并更新项目为已列入计划
	// *
	// * @param projectPlanId
	// * @param projectId
	// * @throws Exception
	// */
	// public void addPlanItemAndUpdateProject(Integer projectPlanId, Integer
	// projectId) throws Exception {
	// this.addPlanItem(projectPlanId, projectId);
	// Project p = (Project) super.getObjectById(projectId, Project.class);
	// p.setIspass(Stct.ISPASS_IS);
	// super.updateObject(p);
	// }

	/**
	 * 添加计划配置
	 * 
	 * @return
	 * @throws Exception
	 */
	public boolean addBulkPlanItem(Integer projectPlanId, String projectIds) throws Exception {
		int[] ids = super.getIntValue(projectIds);
		for (int i = 0; i < ids.length; i++) {
			// this.addPlanItemAndUpdateProject(projectPlanId, ids[i]);
			this.addPlanItem(projectPlanId, ids[i]);
		}
		return true;
	}

	/**
	 * 获取所有计划
	 * 
	 * @return
	 * @throws Exception
	 */
	public List<ProjectPlan> getAllPlan() throws Exception {
		Session s = null;
		try {
			List<ProjectPlan> ppList = null;
			s = SessionProvider.getSession();
			ppList = pd.getAllPlan(s);
			SessionProvider.commitSession(s);
			return ppList;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			throw new Exception(e);
		}
	}

	/**
	 * 获取
	 * 
	 * @return
	 * @throws Exception
	 */
	public List<Project> getProjectListByPlanId(Integer planId) throws Exception {
		List<Project> pList = null;
		List<ProjectPlanItem> ppiList = getPlanItemByPlanId(planId);
		if (O.ckLt(ppiList)) {
			pList = new LinkedList<Project>();
			ProjectService ps = ProjectService.getInService();
			for (ProjectPlanItem ppi : ppiList) {
				Project p = ps.getProjectById(ppi.getProjectId());
				if (null != p) {
					p.setProjectPlanItem(ppi);
					pList.add(p);
				}
			}
		}
		return pList;
	}

	/**
	 * 根据计划名称和分页查询计划数据
	 * 
	 * @param s
	 * @return
	 * @throws Exception
	 */
	public List<ProjectPlan> getPlanListByNameAndPage(String name, String startTime, String endTime, Integer startPage,
			Integer lengthData) throws Exception {
		Session s = null;
		try {
			List<ProjectPlan> ppList = null;
			s = SessionProvider.getSession();
			ppList = pd.getPlanListByNameAndPage(name, startTime, endTime, startPage, lengthData, s);
			SessionProvider.commitSession(s);
			return ppList;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			throw new Exception(e);
		}
	}

	/**
	 * 根据计划名称和分页查询计划数据
	 * 
	 * @param s
	 * @return
	 * @throws Exception
	 */
	public List<ProjectPlan> getPlanListDetails(String name, String startTime, String endTime, Integer startPage,
			Integer lengthData) throws Exception {
		List<ProjectPlan> ppList = this.getPlanListByNameAndPage(name, startTime, endTime, startPage, lengthData);
		if (O.ckLt(ppList)) {
			for (int i = 0; i < ppList.size(); i++) {
				ProjectPlan pp = ppList.get(i);
				int result = this.getCountPlanItemByPlanId(pp.getId());
				pp.setCountProject(result);
			}
		}
		return ppList;
	}

	/**
	 * 根据计划名称和分页查询计划数据长度
	 * 
	 * @param s
	 * @return
	 * @throws Exception
	 */
	public Integer getPlansCountByNameAndPage(String name, String startTime, String endTime) throws Exception {
		Session s = null;
		try {
			int result = 0;
			s = SessionProvider.getSession();
			result = pd.getPlansCountByNameAndPage(name, startTime, endTime, s);
			SessionProvider.commitSession(s);
			return result;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			throw new Exception(e);
		}
	}

	/**
	 * 根据计划ID查询计划配置的数量
	 * 
	 * @param planId
	 * @return
	 * @throws Exception
	 */
	public Integer getCountPlanItemByPlanId(Integer planId) throws Exception {
		Session s = null;
		try {
			int result = 0;
			s = SessionProvider.getSession();
			result = pd.getCountPlanItemByPlanId(planId, s);
			SessionProvider.commitSession(s);
			return result;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			throw new Exception(e);
		}
	}

	/**
	 * 删除计划配置并修改项目为未分配计划
	 * 
	 * @param planItemId
	 * @throws Exception
	 */
	public void deleteProjectPlanItem(Integer ppiid) throws Exception {
		try {
			ProjectPlanItem ppi = (ProjectPlanItem) super.getObjectById(ppiid, ProjectPlanItem.class);
			if (null != ppi) {
				Session s = SessionProvider.getSession();
				int planItemNum = pd.countPlanItem(ppi.getProjectId(), s);
				SessionProvider.commitSession(s);
				if (planItemNum == 0) {
					Project p = (Project) super.getObjectById(ppi.getProjectId(), Project.class);
					if (null != p) {
						p.setIspass(1);
						super.updateObject(p);
					}
				}
			}
			super.deleteObject(ppi);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 根据项目ID查询配置
	 * 
	 * @param projectId
	 * @param s
	 * @return
	 * @throws Exception
	 */
	public List<ProjectPlanItem> getPlanItemByProjectId(Integer projectId) {
		Session s = null;
		try {
			List<ProjectPlanItem> ppiList = null;
			s = SessionProvider.getSession();
			ppiList = pd.getPlanItemByProjectId(projectId, s);
			SessionProvider.commitSession(s);
			return ppiList;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获取
	 * 
	 * @return
	 * @throws Exception
	 */
	public List<Project> planExcelByPlanId(Integer planId) throws Exception {
		List<ProjectPlanItem> ppiList = new ArrayList<ProjectPlanItem>();
		ppiList = getPlanItemByPlanId(planId);
		if (O.ckLt(ppiList)) {
			List<Integer> planIds = new LinkedList<Integer>();
			for (ProjectPlanItem ppi : ppiList) {
				planIds.add(ppi.getProjectId());
			}
			List<Project> pList = new LinkedList<Project>();
			pList = this.projectByPlanId(planIds);
			if (O.ckLt(pList)) {
				for (Project p : pList) {
					CategoryService cs = CategoryService.getInService();
					if (null != p.getFirst_category_id() && p.getFirst_category_id() != 0) {
						FirstCategory fc = cs.getFirstCategory(p.getFirst_category_id());
						p.setFirstCategoryName(fc.getFirst_category_name());
					}
					if (null != p.getThird_category_id() && p.getSecond_category_id() != 0) {
						SecondCategory sc = cs.getSecondCategory(p.getSecond_category_id());
						p.setSecondCategoryName(sc.getSecond_category_name());
					}
					if (null != p.getThird_category_id() && p.getThird_category_id() != 0) {
						ThirdCategory tc = cs.getThirdCategory(p.getThird_category_id());
						p.setThirdCategoryName(tc.getThird_category_name());
					}
					p.setCommentList(cts.listComment(p.getId()));
				}
				return pList;
			}
		}
		return null;
	}

	/**
	 * 根据计划查询项目，并按照一级、二级、三级类别正序排序
	 * 
	 * @param planId
	 * @return
	 * @throws Exception
	 */
	public List<Project> projectByPlanId(List<Integer> planIds) throws Exception {
		Session s = null;
		try {
			List<Project> pList = null;
			s = SessionProvider.getSession();
			pList = projectDao.projectByPlanId(planIds, s);
			SessionProvider.commitSession(s);
			return pList;
		} catch (Exception e) {
			SessionProvider.rollback(s);
			throw new Exception(e);
		}
	}

	/**
	 * 根据计划ID获取计划，并且获取该计划的配置数量
	 */
	public ProjectPlan getPlanAndCountByPlanId(Integer planId) throws Exception {
		ProjectPlan pp = (ProjectPlan) super.getObjectById(planId, ProjectPlan.class);
		int result = this.getCountPlanItemByPlanId(planId);
		pp.setCountProject(result);
		return pp;
	}

	/**
	 * 筛选出项目可以列入的计划
	 * 
	 * @param ppList
	 * @param ppiList
	 * @return
	 */
	public List<ProjectPlan> listPlan(List<ProjectPlan> ppList, List<ProjectPlanItem> ppiList) {
		if (null != ppList && null != ppiList) {
			Map<Integer, Integer> map = new HashMap<Integer, Integer>();
			for (ProjectPlanItem ppi : ppiList) {
				map.put(ppi.getProjectPlanId(), ppi.getProjectPlanId());
			}

			List<ProjectPlan> tempList = new LinkedList<ProjectPlan>();
			for (ProjectPlan pp : ppList) {
				if (null == map.get(pp.getId())) {
					tempList.add(pp);
				}
			}
			return tempList;
		}
		return ppList;
	}

	/**
	 * 补充项目计划详情
	 * 
	 * @param ppiList
	 * @return
	 */
	public List<ProjectPlanItem> infoProjectPlanItem(List<ProjectPlanItem> ppiList) {
		if (O.ckLt(ppiList)) {
			for (ProjectPlanItem ppi : ppiList) {
				ProjectPlan pp = (ProjectPlan) super.getObjectById(ppi.getProjectPlanId(), ProjectPlan.class);
				ppi.setProjectPlan(pp);
			}
		}
		return ppiList;
	}
}